/*
 * TreeContext.cpp
 *
 * Copyright 2012 Fabian Wenzelmann
 *
 * This file is part of Recognition-Procedures-for-Boolean-Functions.
 *
 * Recognition-Procedures-for-Boolean-Functions is free software: you
 * can redistribute it and/or modify it under the terms of the
 * GNU General Public License as published by the Free Software Foundation,
 * either version 3 of the License, or (at your option) any later version.
 *
 * Recognition-Procedures-for-Boolean-Functions is distributed in the hope
 * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 * Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Recognition-Procedures-for-Boolean-Functions.
 *
 * If not, see <http://www.gnu.org/licenses/>.
 */

#include "bfr/lpbCombinatorial/TreeContext.hpp"
#include "bfr/lpbCombinatorial/SplittingTreeNode.hpp"

#include <list>
#include <iostream>

namespace bfr {

TreeContext::TreeContext(size_t vc)
    : tree(tree_t()), variableCount(vc) {
    tree.reserve(vc + 1);
}

TreeContext::~TreeContext() {
    size_t s = size();
    for (size_t i = 0; i < s; i++) {
        delete tree[i];
    }
}

size_t TreeContext::addNode(SplittingTreeNode *node) {
    size_t column = node->getColumn();
    // TODO: we can assume that we add first column 0, then 1, ...?
    if (column == tree.size())
        tree.push_back(new std::list<SplittingTreeNode*>());
    column_t col = tree[column];
    col->push_back(node);
    return col->size() - 1;
}

size_t TreeContext::size() const {
    return tree.size();
}

/*SplittingTreeNode *TreeContext::get(const size_t column, const size_t row)
			const {
    return tree[column]->operator[](row);
}*/

TreeContext::const_col_iterator TreeContext::columnBegin(size_t column) const {
    return tree[column]->begin();
}

TreeContext::const_col_iterator TreeContext::columnEnd(size_t column) const {
    return tree[column]->end();
}

size_t TreeContext::getColumnSize(size_t column) const {
	return tree[column]->size();
}

size_t TreeContext::getVariableCount() const {
    return variableCount;
}

std::ostream& operator<<(std::ostream& os, const TreeContext &c) {
    size_t colNum = 0;
    for (TreeContext::tree_t::const_iterator it = c.tree.begin();
         it != c.tree.end();
         it++) {
        os << "Column " << colNum++ << std::endl;
        const TreeContext::column_t &col = *it;
        for (std::list<SplittingTreeNode*>::const_iterator cit = col->begin();
             cit != col->end();
             cit++) {
            os << *(*cit)->getDNF() << std::endl;
        }
        os << "=============================" << std::endl;
    }
    return os;
}

} // NAMESPACE_BFR
